package Kernel;

import java.io.Serializable;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class Trajet implements Serializable {

	private static final long serialVersionUID = 1L;	
	private String reference;
	private Ville villeDepart;
	private Ville villeArrivee;
	private Vehicule vehicule;
	private GregorianCalendar dateDepart;
	private GregorianCalendar dateArrivee;
	private double tarif;
	private int nbPlacesRestantes;
	private String typeDeBase;

	/* ####### Constructeurs ###### */

	/**
	 * Constructeur par défaut de la classe trajet
	 */
	public Trajet() {
		this.reference = new String();
		this.villeDepart = new Ville();
		this.villeArrivee = new Ville();
		this.vehicule = new Bus();
		this.dateDepart=new GregorianCalendar();
		this.dateArrivee=new GregorianCalendar();
		this.nbPlacesRestantes = vehicule.getCapacite();
		this.tarif=0.0;
		this.typeDeBase=new String();
		
	}

	/**
	 * Constructeur paramétré de la classe trajet
	 * 
	 * @param reference
	 * @param vehicule
	 * @param villeDepart
	 * @param dateDepart
	 * @param villeArrivee
	 * @param dateArrivee
	 * @param tarif
	 * @param typeDeBase
	 */
	public Trajet(String reference, Vehicule vehicule, Ville villeDepart,
			GregorianCalendar dateDepart, Ville villeArrivee,
			GregorianCalendar dateArrivee, double tarif, String typeDeBase) {
		if (dateDepart.before(dateArrivee)
				|| (dateDepart.get(Calendar.DATE) == dateArrivee
						.get(Calendar.DATE)
						&& dateDepart.get(Calendar.MONTH) == dateArrivee
								.get(Calendar.MONTH) && dateDepart
						.get(Calendar.YEAR) == dateArrivee.get(Calendar.YEAR))) {
			this.reference = reference;
			this.vehicule = vehicule;
			this.villeDepart = villeDepart;
			this.villeArrivee = villeArrivee;
			this.dateDepart = dateDepart;
			this.dateArrivee = dateArrivee;
			this.nbPlacesRestantes = vehicule.getCapacite();
			this.tarif = tarif;
			this.typeDeBase = typeDeBase;
		}
	}
	/**
	 * Méthode Date Equal 
	 * @param dateA
	 * 				GregorianCalendar 
	 * @param dateD
	 * 				GregorianCalendar
	 * @return
	 * 				return si deux dates sont equals ou non.
	 */
	public boolean dateEqual(GregorianCalendar dateA, GregorianCalendar dateD) {
		GregorianCalendar dateCourante=new GregorianCalendar();
		dateCourante = (GregorianCalendar) dateA.clone();
		dateCourante.clear(Calendar.HOUR);
		dateCourante.clear(Calendar.MINUTE);
		dateCourante.clear(Calendar.SECOND);
		GregorianCalendar  dateReference = new GregorianCalendar();
		dateReference = (GregorianCalendar) dateD.clone();
		dateReference.clear(Calendar.HOUR);
		dateReference.clear(Calendar.MINUTE);
		dateReference.clear(Calendar.SECOND);
		
		return dateCourante.equals(dateReference);
	}

	/* ##### Fonctions Definies manuellement ###### */

	/**
	 * Réserve une place sur le trajet courant.
	 * @return true si il reste des places, false sinon.
	 */
	public boolean reserverUnePlace() {
		if (getPlacesRestantes()) {
			this.setNbPlacesRestantes(this.nbPlacesRestantes - 1);
			return true;
		} else
			return false;
	}
	
	/**
	 * Méthode pour savoir si le trajet est plein
	 * @return true si il n'y a plus de place, false si il reste des places
	 */
	public boolean estPlein(){
		if(!getPlacesRestantes())
			return true;
		return false;
	}

	/**
	 * Formatter l'objet pour la sauvegarde.
	 * 
	 * @return contient les informations sur l'objet , séparés par des ";"
	 */
	public String print() {
		return this.reference + ";" + this.vehicule.print()
				+ this.villeDepart.print()
				+ this.dateDepart.get(Calendar.DAY_OF_MONTH) + ";"
				+ this.dateDepart.get(Calendar.MONTH) + ";"
				+ this.dateDepart.get(Calendar.YEAR) + ";"
				+this.dateDepart.get(Calendar.HOUR)+";"
				+this.dateDepart.get(Calendar.MINUTE)+";"
				+ this.villeArrivee.print()
				+ this.dateArrivee.get(Calendar.DAY_OF_MONTH) + ";"
				+ this.dateArrivee.get(Calendar.MONTH) + ";"
				+ this.dateArrivee.get(Calendar.YEAR)
				+this.dateArrivee.get(Calendar.HOUR)+";"
				+this.dateArrivee.get(Calendar.MINUTE)+";"
				+this.tarif+";"+this.typeDeBase;
	}

	/* ###### Methodes surchargees ##### */

	@Override
	public String toString() {

        return "Trajet : Reference : " + this.reference + " ,\n Date de depart : "
				+ this.dateDepart.get(Calendar.DAY_OF_MONTH) + "/"
				+ this.dateDepart.get(Calendar.MONTH) + "/"
				+ this.dateDepart.get(Calendar.YEAR)+";"
				+ "\n Heure de départ : "
				+ this.dateDepart.get(Calendar.HOUR)
				+ ": "
				+ this.dateDepart.get(Calendar.MINUTE)
				+ ",\n Ville de depart : "
				+ villeDepart.getNom()
				+ " ,\n Date d'arrivée : "
				+ this.dateArrivee.get(Calendar.DAY_OF_MONTH) + "/"
				+ this.dateArrivee.get(Calendar.MONTH) + "/"
				+ this.dateArrivee.get(Calendar.YEAR)
				+ " ,\n Heure d' Arrivee :"
				+ this.dateArrivee.get(Calendar.HOUR) + ": "
				+ this.dateArrivee.get(Calendar.MINUTE)
				+ ",\n Ville d'arrivee : " + villeArrivee.getNom()
				+ ",\n Moyen de transport : \n" + vehicule.toString()
				+ ",\n Nombre de places restantes : " + nbPlacesRestantes;
	}

	/* ###### Mutateurs ###### */

	public String getReference() {
		return reference;
	}

	public void setReference(String reference) {
		this.reference = reference;
	}

	public Ville getVilleDepart() {
		return villeDepart;
	}

	public void setVilleDepart(Ville villeDepart) {
		this.villeDepart = villeDepart;
	}

	public Ville getVilleArrivee() {
		return villeArrivee;
	}

	public void setVilleArrivee(Ville villeArrivee) {
		this.villeArrivee = villeArrivee;
	}

	public Vehicule getVehicule() {
		return vehicule;
	}

	public void setVehicule(Vehicule vehicule) {
		this.vehicule = vehicule;
	}

	public boolean getPlacesRestantes() {
		return nbPlacesRestantes > 0;
	}

	public int getNbPlacesRestantes() {
		return this.nbPlacesRestantes;
	}

	private void setNbPlacesRestantes(int nbPlacesRestantes) {
		this.nbPlacesRestantes = nbPlacesRestantes;
	}

	public GregorianCalendar getDateDepart() {
        return dateDepart;
    }
	public void setDateDepart(GregorianCalendar date) {
        this.dateDepart = date;
    }

	public GregorianCalendar getDateArrivee() {
        return dateArrivee;
    }
	public void setDateArrivee(GregorianCalendar date) {
        this.dateArrivee = date;
    }

	public double getTarif(){
		return tarif;
	}
	public void setTarif(double tarif) {
		this.tarif = tarif;
	}

	public String getTypeDeBase() {
		return typeDeBase;
	}

	public void setTypeDeBase(String typeDeBase) {
		this.typeDeBase = typeDeBase;
	}
}
